/*******************************************************************************
Coder.cpp

	Author:		LiuDingXi
	e-mail:		liudx@gmail.com
	Date time:	2009-08-17

	Copyright (C) 2009
	All rights reserved.
	
*******************************************************************************/
#include "StdAfx.h"
#include "Coder.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

////////////////////////////////////////////////////////////////////////////////

CCoder::CCoder()
{
}

CCoder::~CCoder()
{
}


static BOOL ForceCreateFolder(LPCTSTR szPathName)
{
	TCHAR szFolder[MAX_PATH];
	_tcscpy(szFolder, szPathName);

	LPTSTR pSlash = _tcsstr(szFolder, _T("\\"));
	if(pSlash == szFolder)
		pSlash = _tcsstr(pSlash+1, _T("\\"));

	while(pSlash)
	{
		*pSlash = _T('\0');
		if(!PathFileExists(szFolder))
		{
			if(!CreateDirectory(szFolder,NULL))
				return FALSE;
		}
		*pSlash = _T('\\');
		pSlash = _tcsstr(pSlash+1, _T("\\"));
	}
	return TRUE;
}


BOOL CCoder::SetFolder(LPCTSTR szFolder)
{
	TCHAR szSrcFolder[MAX_PATH];
	_tcscpy(szSrcFolder, szFolder);
	PathAppend(szSrcFolder, _T("\\src\\"));
	if(!PathFileExists(szSrcFolder))
	{
		ForceCreateFolder(szSrcFolder);
	}
	if(PathFileExists(szSrcFolder))
	{
		m_szSrcFolder = szSrcFolder;
	}

	TCHAR szTplFolder[MAX_PATH];
	_tcscpy(szTplFolder, ".\\");
	PathAppend(szTplFolder, _T("\\tpl\\"));
	if(PathFileExists(szTplFolder))
	{
		m_szTplFolder = szTplFolder;
	}
	return TRUE;
}

BOOL CCoder::Load(LPCTSTR szFileName)
{
	try
	{
		TCHAR szFile[MAX_PATH];
		_tcscpy(szFile, m_szSrcFolder);
		PathAppend(szFile, szFileName);

		CFile file(szFile, CFile::modeRead);
		CArchive ar(&file, CArchive::load);

		m_list.RemoveAll();

		CString s;
		while(ar.ReadString(s))
		{
			m_list.AddTail(s);
		}

		return TRUE;
	}
	catch(CException* e)
	{
		e->ReportError();
		e->Delete();
		return FALSE;
	}
}

BOOL CCoder::Save(LPCTSTR szFileName)
{
	try
	{
		TCHAR szFile[MAX_PATH];
		_tcscpy(szFile, m_szSrcFolder);
		PathAppend(szFile, szFileName);

		CFile file(szFile, CFile::modeCreate|CFile::modeWrite);
		CArchive ar(&file, CArchive::store);

		POSITION pos = m_list.GetHeadPosition();
		while(pos)
		{
			CString s = m_list.GetNext(pos);
			s += _T("\r\n");

			ar.WriteString(s);
		}

		return TRUE;
	}
	catch(CException* e)
	{
		e->ReportError();
		e->Delete();
		return FALSE;
	}
}

BOOL CCoder::LnInsert(LPCTSTR szFlag, LPCTSTR szString, INT nFlag)
{
	POSITION pos = m_list.GetHeadPosition();
	while(pos)
	{
		CString s = m_list.GetNext(pos);
		if(s.Find(szFlag) != -1)
		{
			POSITION pat = pos;
			m_list.GetPrev(pat);
			if(nFlag == LN_AFTER)
			{
				m_list.InsertAfter(pat, szString);
			}
			else if(nFlag == LN_BEFORE)
			{
				m_list.InsertBefore(pat, szString);
			}
			return TRUE;
		}
	}
	return FALSE;	
}

BOOL CCoder::LnRemove(LPCTSTR szFlag, LPCTSTR szString, INT nFlag)
{
	BOOL bFlag = FALSE;
	POSITION pos = m_list.GetHeadPosition();
	while(pos)
	{
		CString s = m_list.GetAt(pos);
		if(s.Find(szFlag) != -1)
		{
			if(nFlag == LN_BEFORE)
			{
				return FALSE;
			}
			bFlag = TRUE;
		}
		else if(bFlag && nFlag == LN_AFTER)
		{
			if(s == szString)
			{
				m_list.RemoveAt(pos);
				return TRUE;
			}
		}
		else if(bFlag && nFlag == LN_BOUND)
		{
			if(s.Find(szString) != -1)
			{
				return TRUE;
			}
			else
			{
				POSITION pat = pos;
				m_list.GetNext(pos);
				m_list.RemoveAt(pat);
				if(pos == NULL)
					return TRUE;
				else
				{
					continue;
				}
			}
		}
		else if(nFlag == LN_BEFORE)
		{
			if(s == szString)
			{
				m_list.RemoveAt(pos);
				return TRUE;
			}
		}
		m_list.GetNext(pos);
	}
	return FALSE;	
}

BOOL CCoder::TemplateOf(LPCTSTR szTplFile, LPCTSTR szTarFile, LPCTSTR szOld, LPCTSTR szNew)
{
	try
	{
		CFile file(szTplFile, CFile::modeRead);
		CFile save(szTarFile, CFile::modeCreate|CFile::modeWrite);

		CArchive ar(&file, CArchive::load);
		CArchive sr(&save, CArchive::store);

		CString s;
		while(ar.ReadString(s))
		{
			s.Replace(szOld, szNew);
			
			sr.WriteString(s);
			sr.WriteString(_T("\r\n"));
		}

		return TRUE;
	}
	catch(CException* e)
	{
		e->ReportError();
		e->Delete();
		return FALSE;
	}
}

BOOL CCoder::TemplateFor(LPCTSTR szOldFile, LPCTSTR szOld, LPCTSTR szNew, LPCTSTR szNewFile)
{
	TCHAR szTplFile[MAX_PATH];
	_tcscpy(szTplFile, m_szTplFolder);
	PathAppend(szTplFile, szOldFile);

	TCHAR szTarFile[MAX_PATH];
	_tcscpy(szTarFile, m_szSrcFolder);
	PathAppend(szTarFile, szNewFile);

	
	LPTSTR pTail1 = szTplFile;
	while(*pTail1) pTail1++;

	LPTSTR pTail2 = szTarFile;
	while(*pTail2) pTail2++;


	_tcscpy(pTail1, _T(".cpp"));
	_tcscpy(pTail2, _T(".cpp"));
	
	if(!TemplateOf(szTplFile, szTarFile, szOld, szNew))
	{
		return FALSE;
	}

	_tcscpy(pTail1, _T(".h"));
	_tcscpy(pTail2, _T(".h"));
	
	if(!TemplateOf(szTplFile, szTarFile, szOld, szNew))
	{
		return FALSE;
	}

	return TRUE;
}

BOOL CCoder::HasSrcFile(LPCTSTR szFileName)
{
	TCHAR szTarFile[MAX_PATH];
	_tcscpy(szTarFile, m_szSrcFolder);
	PathAppend(szTarFile, szFileName);

	
	LPTSTR pTail2 = szTarFile;
	while(*pTail2) pTail2++;

	_tcscpy(pTail2, _T(".cpp"));
	
	if(!PathFileExists(szTarFile))
	{
		return FALSE;
	}

	_tcscpy(pTail2, _T(".h"));
	
	if(!PathFileExists(szTarFile))
	{
		return FALSE;
	}	
	return TRUE;
}
